<!--
http://localhost:63343/socket/index.html?from_id=2&to_id=5
https://blog.csdn.net/yournevermore/article/details/102936224  心跳
-->
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="format-detection" content="telephone=no"/>
    <title>交流中</title>
    <link rel="stylesheet" type="text/css" href="./static/newcj/css/themes.css?v=2017129">
    <link rel="stylesheet" type="text/css" href="./static/newcj/css/h5app.css">
    <link rel="stylesheet" type="text/css" href="./static/newcj/fonts/iconfont.css?v=2016070717">
    <script src="./static/newcj/js/jquery.min.js"></script>
    <script src="./static/newcj/js/dist/flexible/flexible_css.debug.js"></script>
    <script src="./static/newcj/js/dist/flexible/flexible.debug.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.10.6/dayjs.min.js"></script>
</head>
<body ontouchstart>
<div class='fui-page-group'>
    <div class='fui-page chatDetail-page'>
        <div class="chat-header flex">
            <span class="shop-titlte t-30">交流中</span>
        </div>
        <div class="fui-content navbar" style="padding:1.2rem 0 1.35rem 0;">
            <div class="chat-content">
                <p style="display: none;text-align: center;padding-top: 0.5rem" id="more"><a>加载更多</a></p>
                <p class="chat-time"><span class="time" id="current_time"></span></p>
            </div>
        </div>
        <div class="fix-send flex footer-bar">
            <input class="send-input t-28" maxlength="200">
            <span class="send-btn">发送</span>
        </div>
    </div>
</div>

<script>
    $(function () {
        let currentTime = dayjs(Date.now()).format('YYYY-MM-DD HH:mm:ss')
        let lockReconnect = false       //避免重复连接
        let ws = null       //WebSocket的引用
        let wsUrl = "wss://school.qifuxiong.com/wss/"
        let fromId = getQueryVariable('from_id')  //url中获取参数
        let toId = getQueryVariable('to_id')  //url中获取参数

        //创建WebSocket连接
        function createWebSocket(url) {
            try {
                ws = new WebSocket(url);
                // 核心代码
                initEventHandle();
            } catch (e) {
                // 重连
                reconnect(url);
            }
        }

        /********************初始化开始************************/
        function initEventHandle() {
            // 连接成功建立后响应
            ws.onopen = function () {
                console.log("成功连接到: socket");
                // 心跳检测重置
                heartCheck.reset().start();
            }
            // 收到服务器消息后响应
            ws.onmessage = function (e) {
                //如果获取到消息，心跳检测重置
                //拿到任何消息都说明当前连接是正常的
                heartCheck.reset().start();
                //Json转换成Object
                let message = eval("(" + e.data + ")");
                console.log('服务端返回的数据', message) //socket返回的信息

                switch (message.type) {
                    case "init":
                        // 发送用户id, 后端拿到这个数据, 绑定fd
                        let build = {
                            type: "bind",
                            fromId: fromId
                        }
                        ws.send(JSON.stringify(build));

                        //  省略:  请求后端api, 拿到双方历史聊天记录, 渲染; 后面, 每次发送数据后, 都需要先发送(socket实时返回), 后请求后端api接口, 进行信息入库操作


                        // 点对点聊天判断对方是否在线,
                        let online = {
                            type: 'online',
                            to_id: toId,
                            from_id: fromId,
                        }
                        ws.send(JSON.stringify(online));

                        return
                    case "text":
                        if (toId == message.from_id) {
                            $(".chat-content").append(' <div class="chat-text section-left flex"><span class="char-img" style="background-image: url(./static/newcj/img/123.jpg)"></span> <span class="text"><i class="icon icon-sanjiao4 t-32"></i>' + message.data + '</span> </div>');
                            $(".chat-content").scrollTop(3000);
                        }
                        return
                    case 'heart':
                        console.log('心跳不渲染任何信息')
                        return
                    case 'online':
                        //  用户在线不在线, 涉及到一些业务场景需要处理
                        //  如果对方上线了, 后端也会主动推送到这个里面来
                        // 如果用户下线了, 后端也会主动推送到这个里面来
                        console.log(message.to_id + message.status)
                        return
                    default:
                        console.log('格式问题, 后端不存在这种形式返回')
                        return
                }
            }
            // 链接关闭后响应
            ws.onclose = function () {
                console.log('连接关闭, 正在重连')
                reconnect(wsUrl)    //重连
            }
            ws.onerror = function () {
                console.log('连接错误, 正在重连')
                reconnect(wsUrl)    //重连
            }
        }

        /*********************初始化结束*************************/
        $(".send-btn").click(function () {
            if (ws.readyState == 1) {
                let text = $(".send-input").val();
                let message = {
                    data: text,
                    type: 'say',
                    from_id: fromId,
                    to_id: toId
                }
                $(".chat-content").append('<div class="chat-text section-right flex"><span class="text"><i class="icon icon-sanjiao3 t-32"></i>' + text + '</span> <span class="char-img" style="background-image: url(./static/newcj/img/132.jpg)"></span> </div>')
                ws.send(JSON.stringify(message));
                $(".send-input").val("");
            } else {
                alert("当前连接超时，请刷新重试!");
            }
            return false
        })
        // 强制退出
        window.onunload = function () {
            console.log('我强退了!!!')
            ws.close()
        }

        // 心跳检测
        let heartCheck = {
            timeout: 30000,//毫秒
            timeoutObj: null,
            serverTimeoutObj: null,
            reset: function () {
                clearTimeout(this.timeoutObj);
                clearTimeout(this.serverTimeoutObj);
                return this;
            },
            start: function () {
                let self = this;
                this.timeoutObj = setTimeout(function () {
                    //这里发送一个心跳，后端收到后，返回一个心跳消息，
                    //onmessage拿到返回的心跳就说明连接正常
                    let heart = {
                        type: "heart",
                        fromId: fromId
                    }
                    ws.send(JSON.stringify(heart));
                    console.log("发送一次心跳包", heart);
                    self.serverTimeoutObj = setTimeout(function () {//如果超过一定时间还没重置，说明后端主动断开了
                        ws.close();//如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                    }, self.timeout)
                }, this.timeout)
            }
        }

        //WebSocket重接
        function reconnect(url) {
            if (lockReconnect) return
            lockReconnect = true
            //没连接上会一直重连，设置延迟避免请求过多
            setTimeout(function () {
                createWebSocket(url);
                console.log('正在重连, 当前时间: '.currentTime)
                lockReconnect = false
            }, 5000) // 这里设置重连间隔(ms)
        }

        // url中获取参数
        function getQueryVariable(variable) {
            let query = window.location.search.substring(1);
            let vars = query.split("&");
            for (let i = 0; i < vars.length; i++) {
                let pair = vars[i].split("=");
                if (pair[0] == variable) {
                    return pair[1];
                }
            }
            return (false);
        }

        createWebSocket(wsUrl) /**启动连接**/


    })
</script>
</body>
</html>
